package com.wz.utils.jvm.tune;

/**
 * @Author : Wang Zhen.
 * @Date : Created in 19:10 2022/10/19
 * @Description :  在 JDK 1.6 下输出是 false，创建了 6 个对象
 * 在 JDK 1.7 及以上的版本输出是 true，创建了 5 个对象
 * 当然我们这里没有考虑GC，但这些对象确实存在或存在过
 * @Modified By   :
 * @Version :
 */
public class ConstantPool {
    public static void main(String[] args) {
        String s1 = new String("he") + new String("llo");
        String s2 = s1.intern();
        System.out.println(s1 == s2);


        test01();
        test02();
        test03();
        test04();
        test05();
        test06();
        test07();
        test08();
    }

    public static void test01() {
        String s0 = "zhuge";
        String s1 = "zhuge";
        String s2 = "zhu" + "ge";
        System.out.println(s0 == s1); //true
        System.out.println(s0 == s2); //true
    }

    public static void test02() {
        String s0 = "zhuge";
        String s1 = new String("zhuge");
        String s2 = "zhu" + new String("ge");
        System.out.println(s0 == s1); // false
        System.out.println(s0 == s2);  // false
        System.out.println(s1 == s2); // false
    }

    public static void test03() {
        String a = "a1";
        String b = "a" + 1;
        System.out.println(a == b); // true

        String a1 = "atrue";
        String b1 = "a" + "true";
        System.out.println(a1 == b1); // true

        String a2 = "a3.4";
        String b2 = "a" + 3.4;
        System.out.println(a2 == b2); // true
    }


    public static void test04() {
        String a = "ab";
        String bb = "b";
        String b = "a" + bb;

        System.out.println(a == b); // false
    }

    public static void test05() {
        String a = "ab";
        final String bb = "b";
        String b = "a" + bb;

        System.out.println(a == b); // true
    }


    public static void test06() {
        String a = "ab";
        final String bb = getBB();
        String b = "a" + bb;

        System.out.println(a == b); // false

    }

    private static String getBB() {
        return "b";
    }

    public static void test07() {
        String s = "a" + "b" + "c";  //就等价于String s = "abc";
        String a = "a";
        String b = "b";
        String c = "c";
        String s1 = a + b + c;
    }

    public static void test08() {
        //字符串常量池："计算机"和"技术"     堆内存：str1引用的对象"计算机技术"
//堆内存中还有个StringBuilder的对象，但是会被gc回收，StringBuilder的toString方法会new String()，这个String才是真正返回的对象引用
        String str2 = new StringBuilder("计算机").append("技术").toString();   //没有出现"计算机技术"字面量，所以不会在常量池里生成"计算机技术"对象
        System.out.println(str2 == str2.intern());  //true
//"计算机技术" 在池中没有，但是在heap中存在，则intern时，会直接返回该heap中的引用

//字符串常量池："ja"和"va"     堆内存：str1引用的对象"java"
//堆内存中还有个StringBuilder的对象，但是会被gc回收，StringBuilder的toString方法会new String()，这个String才是真正返回的对象引用
        String str1 = new StringBuilder("ja").append("va").toString();    //没有出现"java"字面量，所以不会在常量池里生成"java"对象
        System.out.println(str1 == str1.intern());  //false
//java是关键字，在JVM初始化的相关类里肯定早就放进字符串常量池了

        String s1 = new String("test");
        System.out.println(s1 == s1.intern());   //false
//"test"作为字面量，放入了池中，而new时s1指向的是heap中新生成的string对象，s1.intern()指向的是"test"字面量之前在池中生成的字符串对象

        String s2 = new StringBuilder("abc").toString();
        System.out.println(s2 == s2.intern());  //false
//同上
    }
}
